package com.fingard.dsp.bank.directbank.cmb05;

import cn.com.infosec.util.Base64;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.dbobj.receipt.ReceiptData;
import com.fingard.dsp.bank.dbobj.receipt.ReceiptDataHelper;
import com.fingard.dsp.bank.directConfig.ReceiptProConfig;
import com.fingard.dsp.bank.directbank.bankInterface.IReceiptPro;
import com.fingard.dsp.bank.reqrespobj.downloadreceipt.ReqQryReceipt;
import com.fingard.dsp.bank.reqrespobj.downloadreceipt.RetAtsReceipt;
import com.fingard.text.StringHelper;
import com.google.gson.Gson;
import net.sf.json.JSONArray;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName CMB05Receipt
 * @Author Zhengzy
 * @Date 2020/3/27 15:06
 * @Version 1.0
 **/
public class CMB05ReceiptPro extends CMB05Base implements IReceiptPro {

    /**
     * 解析base64加密数据并存储
     *
     * @param oldStr
     * @param fileName
     * @throws IOException
     */
    public void decodeData(String oldStr, String fileName, ReceiptProConfig pConfig, ReqQryReceipt pReqReceipt, Date pOneDay) throws Exception {
        ReceiptDataHelper receiptHelper = new ReceiptDataHelper(pReqReceipt.reqHeader.tenant, pOneDay);
        String qryDay8 = Format.Date8Format.format(pOneDay);
        String localpath = pConfig.getSaveSubDir(pReqReceipt.reqHeader, pOneDay) + File.separator + qryDay8;
        byte[] content = Base64.decode(oldStr);
        //WriteBankLogLn("base64解密后的文件Str：" + content.toString());
        // 读取配置路径，可根据自己需求改路径
        //String path = getBankConfig().getValueAsString("fileDir");
        File file = new File(localpath);
        if (!file.exists()) {
            file.mkdirs();
            WriteBankLogLn("创建pdf存储文件目录：" + localpath);
        }
        String fileDir = localpath + File.separator + fileName;
        FileOutputStream fos = new FileOutputStream(fileDir);
        fos.write(content, 0, content.length);
        fos.close();
    }

    @Override
    public RetAtsReceipt qryReceiptOneDay(ReceiptProConfig pConfig, ReqQryReceipt pReqReceipt, Date pOneDay) throws Exception {
        ReceiptDataHelper receiptHelper = new ReceiptDataHelper(pReqReceipt.reqHeader.tenant, pOneDay);//回单数据保存类，分区分表

        StringBuffer sbf = new StringBuffer();
        CMB05Header bankHeader = new CMB05Header();
        bankHeader.transCode = "DCFDFBRT";
        // 组装报文前缀
        writeCommonHeader(sbf, bankHeader);
        // 组装请求报文体json
        JSONObject json = new JSONObject();
        HashMap<String, Object> requestMap = new HashMap<String, Object>();
        HashMap<String, String> headMap = new HashMap<String, String>();
        headMap.put("funcode", bankHeader.transCode);
        headMap.put("userid", bankFront.loginName);
        requestMap.put("head", headMap);
        HashMap<String, Object> bodyMap = new HashMap<String, Object>();
        bodyMap.put("eacnbr", pReqReceipt.actNum);// 账号
        bodyMap.put("begdat", Format.Date10Format.format(pOneDay));// 起始日期 yyyy-MM-dd格式
        bodyMap.put("enddat", Format.Date10Format.format(pOneDay));// 结束日期
        bodyMap.put("rrcflg", "1");// 打印标志 1:未打印 2:已打印
        requestMap.put("body", bodyMap);
        json.put("request", requestMap);
        sbf.append(JSON.toJSONString(json));
        int flag = 1;// 续传标志 0不续传，1续传
        while (flag == 1) {
            String[] tmpStrRet = sendToBank(sbf.toString());
//            String[] tmpStrRet= {"", ""};
            if (tmpStrRet[0].length() == 0) {
                // 把结果转成json
                JSONObject response = JSON.parseObject(tmpStrRet[1]);
                if (response != null) {
                    String info = response.getString("response");
                    JSONObject content = JSON.parseObject(info);
                    String head = content.getString("head");
                    String body = content.getString("body");
                    Gson gson = new Gson();// 解析json用
                    Map<String, String> headInfo = new HashMap<String, String>();
                    headInfo = gson.fromJson(head, headInfo.getClass());
                    if (headInfo != null) {
                        String responseCode = headInfo.get("resultcode");
                        String responseMsg = headInfo.get("resultmsg");
                        if ("SUC0000".equals(responseCode)) {
                            JSONObject bodyInfos = JSON.parseObject(body);
                            String args = bodyInfos.getString("csrrcfdfz2");// 回单数据
                            // 有该对象返回时表明需要续传，将该对象下所有内容拷贝到请求报文的body继续查询。
                            String ctnkey = bodyInfos.getString("ctnkey");// 回传数据
                            if ("null".equals(ctnkey) || StringHelper.isNullOrEmpty(ctnkey)) {
                                // 不需要续传
                                flag = 0;
                                WriteBankLogLn("不需要续传，ctnkey：" + ctnkey);
                            } else {
                                // 需要续传
                                sbf = new StringBuffer();
                                writeCommonHeader(sbf, bankHeader);
                                requestMap.remove("body");
                                bodyMap.put("body", ctnkey);
                                json.put("requeset", requestMap);
                                sbf.append(JSON.toJSONString(json));
                            }
                            JSONArray array = JSONArray.fromObject(args);
                            for (int i = 0; i < array.size(); i++) {
                                String record = array.getString(i);
                                Map<String, String> recordInfo = new HashMap<String, String>();
                                recordInfo = gson.fromJson(record, recordInfo.getClass());
                                String encryptData = recordInfo.get("fildat");// Base64后的数据，Base64解码后写入文件可得到PDF
                                String fileName = recordInfo.get("filnam");// 命名规则：账号_起始日期_结束日期_回单编号_流水号（流水号同6.1.2返回报文中的trsseq可以关联起来。）
                                // String fileLen = recordInfo.get("fillen") + "";// 文件长度
                                WriteBankLogLn("银行返回的回单名称：" + fileName);
                                ReceiptData rcpt = new ReceiptData();
                                // 解密fildat并转pdf
                                decodeData(encryptData, fileName, pConfig, pReqReceipt, pOneDay);

                                // 保存数据到数据库
                                rcpt.localFile = "";
                                rcpt.ownAct = pReqReceipt.actNum;
                                rcpt.srcSys = "CMB05";
                                rcpt.bank = "308";
                                rcpt.receiptNo = fileName.split("_")[3];
                                rcpt.istNbr = rcpt.receiptNo;
                                rcpt.busDate = Integer.parseInt(fileName.split("_")[1].replaceAll("-", ""));

                                int inRe = receiptHelper.insertIfNotExist(rcpt, true);
                                WriteBankLogLn2("回单编号：" + rcpt.receiptNo + "写入数据库，影响行数：" + inRe);

                                // 更改数据库回单状态等
                                //数据库中存储的路径是相对pConfig.localSaveMainDir的相对路径
                                String qryDay8 = Format.Date8Format.format(pOneDay);
                                String localpath = pConfig.getSaveSubDir(pReqReceipt.reqHeader, pOneDay) + File.separator + qryDay8;
                                String pReceiptDir = localpath + "/" + fileName;
                                File receiptDir = new File(pReceiptDir);
                                String relativePath = StringHelper.getRelativePath(receiptDir.getAbsolutePath(), pConfig.localSaveMainDir).trim();
                                int inRe1 = receiptHelper.updateDownState(pReqReceipt.actNum, rcpt.receiptNo, relativePath, receiptDir.getName(), "2");
                                WriteBankLogLn("回单编号" + rcpt.receiptNo + "，文件" + receiptDir.getName() + "更新影响行数：" + inRe1);
                            }
                        } else {
                            flag = 0; // 返回异常，不续传，无法续传
                            WriteBankLogLn(responseMsg);
                        }
                    }
                } else {
                    flag = 0;
                    WriteBankLogLn("请求未正常返回");
                }
            } else {
                flag = 0;
                WriteBankLogLn(tmpStrRet[1]);
            }
        }
        return null;
    }
}
